﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Dynamic;
using System.Web.Script.Serialization;
using System.Runtime.Serialization.Json;
using System.IO;
using System.Xml.Serialization;
using System.Web;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;
using System.Runtime.Remoting.Messaging;
using Common.Reflection;

namespace System
{
    public static class ObjectConvertExtension
    {
        /// <summary>
        /// Serializes a serializable object to XML
        /// </summary>
        /// <typeparam name="T">The type of the members of values.</typeparam>
        /// <param name="anonymousObject">Serializable Object</param>
        /// <returns>XML string of the object</returns>
        public static string ToXml<T>(this object anonymousObject)
        {
            XmlSerializer xml = new XmlSerializer(typeof(T));

            using (MemoryStream ms = new MemoryStream())
            {

                xml.Serialize(ms, anonymousObject);

                return Encoding.UTF8.GetString(ms.ToArray());
            }
        }

        /// <summary>
        /// Serializes a serializable object to XML
        /// </summary>
        /// <param name="anonymousObject">Serializable Object</param>
        /// <returns>XML string of the object</returns>
        public static string ToXml(this object anonymousObject)
        {
            XmlSerializer xml = new XmlSerializer(anonymousObject.GetType());

            using (MemoryStream ms = new MemoryStream())
            {

                xml.Serialize(ms, anonymousObject);

                return Encoding.UTF8.GetString(ms.ToArray());
            }
        }

        /// <summary>
        /// Serializes a serializable object to JSON
        /// </summary>
        /// <param name="anonymousObject">Serializable Object</param>
        /// <returns>JSON string of the object</returns>
        public static string ToJSON(this object anonymousObject)
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();

            return serializer.Serialize(anonymousObject);
        }

        /// <summary>
        /// Serializes a serializable object to JSON
        /// Note: WCF JSON string. Uses DataContract Serializer.
        /// </summary>
        /// <typeparam name="T">The type of the members of values.</typeparam>
        /// <param name="anonymousObject">Serializable Object</param>
        /// <returns>JSON string of the object</returns>
        public static string ToJSON2<T>(this object anonymousObject)
        {
            DataContractJsonSerializer json = new DataContractJsonSerializer(typeof(T));

            using (MemoryStream ms = new MemoryStream())
            {

                json.WriteObject(ms, anonymousObject);

                return Encoding.UTF8.GetString(ms.ToArray());
            }
        }

        /// <summary>
        /// Serializes a serializable object to JSON
        /// Note: WCF JSON string. Uses DataContract Serializer.
        /// </summary>
        /// <param name="anonymousObject">Serializable Object</param>
        /// <returns>JSON string of the object</returns>
        public static string ToJSON2(this object anonymousObject)
        {
            DataContractJsonSerializer json = new DataContractJsonSerializer(anonymousObject.GetType());

            using (MemoryStream ms = new MemoryStream())
            {

                json.WriteObject(ms, anonymousObject);

                return Encoding.UTF8.GetString(ms.ToArray());
            }
        }

        /// <summary>
        /// Updates or Adds a object of a type to a Http Session.
        /// </summary>
        /// <typeparam name="T">The type of the members of values.</typeparam>
        /// <param name="anonymousObject">Current object. Can not be null.</param>
        /// <param name="SessionKeyName">Session key name</param>
        /// <returns>The type of the members of values.</returns>
        public static T ToWebSession<T>(this object anonymousObject, string SessionKeyName)
        {
            try
            {
                if (anonymousObject.isNull()) return anonymousObject.ToType<T>();
                if (String.IsNullOrEmpty(SessionKeyName)) SessionKeyName = anonymousObject.GetGuid().ToString();

                HttpContext.Current.Session[SessionKeyName] = anonymousObject;
            }
            catch
            {
            }

            return anonymousObject.ToType<T>();
        }

        /// <summary>
        /// Updates or Adds a object of a type to a Http Session.
        /// </summary>
        /// <typeparam name="T">The type of the members of values.</typeparam>
        /// <param name="anonymousObject">Current object. Can not be null.</param>
        /// <param name="SessionIndex">Session idex of the session collection.</param>
        /// <returns>The type of the members of values.</returns>
        public static T ToWebSession<T>(this object anonymousObject, int SessionIndex)
        {
            try
            {
                if (anonymousObject.isNull()) return anonymousObject.ToType<T>();
                if (SessionIndex < 1) throw new IndexOutOfRangeException("SessionIndex");

                HttpContext.Current.Session[SessionIndex] = anonymousObject;
            }
            catch (Exception ex)
            {
                throw ex;
            }

            return anonymousObject.ToType<T>();
        }
    }
}
